package com.pearadmin.pro.common.security.authent;

import com.alibaba.fastjson.JSON;
import com.pearadmin.pro.common.constant.SecurityConstant;
import com.pearadmin.pro.common.constant.TokenConstant;
import com.pearadmin.pro.common.security.subject.CustomUserDetails;
import com.pearadmin.pro.common.tools.web.ServletUtil;
import com.pearadmin.pro.common.web.domain.Result;
import com.pearadmin.pro.common.web.exception.auth.TokenException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;

/**
 * Describe: Security Basic Filter 主要增加 Token 的验证
 * Author: 就 眠 仪 式
 * CreateTime: 2019/10/23
 * */
public class CustomTokenAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    private RedisTemplate<String,CustomUserDetails> redisTemplate;

    public CustomTokenAuthenticationFilter(AuthenticationManager authenticationManager){

        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

            String tokenHeader = request.getHeader(TokenConstant.TOKEN_HEADER);

            if (null == tokenHeader) {
                ServletUtil.write(JSON.toJSONString(Result.failure("Token 缺失")));
                return;
            }

            if (!tokenHeader.startsWith(TokenConstant.TOKEN_PREFIX)) {
                ServletUtil.write(JSON.toJSONString(Result.failure("Token 无效")));
                return;
            }

            String token = request.getHeader(TokenConstant.TOKEN_HEADER).replace(TokenConstant.TOKEN_PREFIX, "");
            CustomUserDetails customUserDetails = redisTemplate.opsForValue().get(token);

            if (redisTemplate.opsForValue().get(token) == null) {
                ServletUtil.write(JSON.toJSONString(Result.failure("Token 过期")));
                return;
            }

            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(customUserDetails, customUserDetails.getUserId(), customUserDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            chain.doFilter(request, response);
            return;
    }
}
